﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace Report
{
    public class ReportManager
    {
        private Serializer serializer = new Serializer();
        public void SaveToDb()
        {
            var path = Assembly.GetExecutingAssembly().Location;
            serializer.SerializeObject(Path.Combine(Path.GetDirectoryName(path), "db.bin"), DbProvider.Data);

        }
        public void SaveToDB(IList<IItem> items,bool append)
        {

            if (!append)
            {
                DbProvider.Data = new Composite() {Name = Const.GenMuLu,FirstLevel = "总计"};
            }
            foreach (var rItem in items.Where(r=>r.FirstLevel != "总计"))
            {
                if (!string.IsNullOrEmpty(rItem.FirstLevel) && DbProvider.Data.GetbyName(rItem.FirstLevel) == null)
                {
                    DbProvider.Data.Add(new Composite() { Name = rItem.FirstLevel,FirstLevel = rItem.FirstLevel,ContentSummary = string.Empty});

                }
                if (!string.IsNullOrEmpty(rItem.SecondLevel) && DbProvider.Data.GetbyName(rItem.SecondLevel) == null)
                {
                    var item = DbProvider.Data.GetbyName(rItem.FirstLevel);
                    item.Add(new Composite() {Name = rItem.SecondLevel,SecondLevel = rItem.SecondLevel,FirstLevel = rItem.FirstLevel,ContentSummary = string.Empty});
                }
                if (!string.IsNullOrEmpty(rItem.ContentSummary))
                {
                    var parentName = string.Empty;
                    if (!string.IsNullOrEmpty(rItem.FirstLevel))
                    {
                        parentName = rItem.FirstLevel;
                    }
                    if (!string.IsNullOrEmpty(rItem.SecondLevel))
                    {
                        parentName = rItem.SecondLevel;
                    }
                 
                    var item = DbProvider.Data.GetbyName(parentName);
                    item.Add(new Leaf()
                    {
                        Name = rItem.ContentSummary,
                        ContentSummary = rItem.ContentSummary,
                        Borrow = rItem.Borrow,
                        Comment = rItem.Comment,
                        AddDate = rItem.AddDate,
                        Lent = rItem.Lent,
                        FirstLevel = rItem.FirstLevel,
                        SecondLevel = rItem.SecondLevel,
                        Income = rItem.Income,
                        Cost = rItem.Cost
                    });
                }
            }
            SaveToDb();
        }
        public void LoadDataFromDB()
        {
            var path = Assembly.GetExecutingAssembly().Location;
            var fileanme = Path.Combine(Path.GetDirectoryName(path), "db.bin");
            if (!File.Exists(fileanme))
            {
                return;
            }
            DbProvider.Data = serializer.DeSerializeObject(fileanme);
        }
        public void InitializeDatawithReport(TreeNode node,IItem item,TreeView treeView)
        {
            if (item is Leaf)
                return;
            
            if (item.Name != Const.GenMuLu)
            {
                node.Text = item.Name;
            }
            else
            {
                treeView.Nodes.Clear();
            }
            var children = item.GetChildern();
            foreach (var child in children)
            {
                if (child is Leaf)
                    continue;
                
                var childNode = new TreeNode(child.Name);

                if (item.Name == Const.GenMuLu)
                {
                    treeView.Nodes.Add(childNode);
                }
                else
                {
                    node.Nodes.Add(childNode);
                }
                InitializeDatawithReport(childNode,child,treeView);
            }
        }

        public IList<IItem> BuildFlatList(IItem item)
        {
            var list = new List<IItem>();
            list.Add(item);
            foreach (var item1 in item.GetChildern())
            {
                list.AddRange(BuildFlatList(item1));
            }
            return list;
        }
        public IList<string> GetCategoryNames()
        {
            var result = new List<string>();
            var data = DbProvider.Data;
            foreach (var d in data.GetChildern().OfType<Composite>())
            {
                result.Add(d.Name);
                result.AddRange(d.GetChildern().OfType<Composite>().Select(e => e.Name));
            }
            return result;
        }
        public IList<IItem> BuildDetailList()
        {
            var list = new List<IItem>();
            var data = DbProvider.Data;
            foreach (var vItem in data.GetChildern())
            {
                list.Add(vItem);
                float ic = 0,ishouldhave = 0;
                foreach (var rItem in vItem.GetChildern())
                {
                    if (rItem is Composite)
                    {
                        list.Add(rItem);
                        float income = 0,shouldHaveincome = 0;
                        foreach (var item in rItem.GetChildern())
                        {
                          
                            income += item.ExistingIncome;
                            item.ExistingIncome = income;
                            shouldHaveincome = shouldHaveincome + item.Lent - item.Borrow;

                            item.ShouldHaveIncome = item.ExistingIncome + shouldHaveincome;
                            list.Add(item);
                        }
                    }
                    else
                    {
                        var i = rItem;
                        ic += i.ExistingIncome;
                        i.ExistingIncome = ic;
                        ishouldhave = ishouldhave + i.Lent - i.Borrow;
                        i.ShouldHaveIncome = i.ExistingIncome + ishouldhave;
                        list.Add(i);

                    }
                }
               
            }
            list.Add(DbProvider.Data);
            return list;
        }
        public IList<IItem> GetListbyName(IItem item, string name)
        {
            var list = BuildFlatList(item);
            return list.Where(r => r.Name.Contains(name)).ToList();
        }

        public IList<IItem> BuildReportList(IItem item, string parentName)
        {
            var list = new List<IItem>();
            var items = item.GetChildern().Where(r=>r is Leaf);
            var groups = items.OrderBy(r => r.AddDate).GroupBy(e => e.AddDate);
            foreach (var group in groups)
            {
                var costtotal = group.Sum(r => r.Cost);
                var incoome = group.Sum(r => r.Income);
                var borrow = group.Sum(r => r.Borrow);
                var lent = group.Sum(r => r.Lent);
                list.Add(parentName == Const.GenMuLu
                             ? new Leaf 
                                 {
                                     AddDate = @group.Key,
                                     Cost = costtotal,
                                     Income = incoome,
                                     Borrow = borrow,
                                     Lent = lent,
                                     Name = string.Empty,
                                     FirstLevel = item.Name,
                                     Comment = item.Comment
                                     
                                 }
                             : new Leaf
                                 {
                                     AddDate = @group.Key,
                                     Cost = costtotal,
                                     Income = incoome,
                                     SecondLevel = item.Name,
                                     Name = item.Name,
                                     FirstLevel = parentName,
                                     Comment = item.Comment,
                                     Borrow = borrow,
                                     Lent = lent,
                                 });
            }
            
            foreach (var item1 in item.GetChildern().Where(r=>r is Composite))
            {
               list.AddRange(BuildReportList(item1,item.Name));
            }
            return list;
        }

        public void InitializeGridView2(DataGridView dataGridView1, IList<IItem> list)
        {
            dataGridView1.Columns.Clear();

            dataGridView1.AutoGenerateColumns = false;
            //  dataGridView1.AutoSize = true;
            dataGridView1.DataSource = list;
            ColumnInitialize(dataGridView1);
            DataGridViewColumn column5 = new CalendarColumn();
            column5.DataPropertyName = "AddDate";
            column5.Name = "时间";
            dataGridView1.Columns.Insert(0, column5);


            foreach (DataGridViewColumn item in dataGridView1.Columns)
            {
                item.ReadOnly = true;
            }
        }

        public void InitializeGridView(DataGridView dataGridView1, IList<IItem> list)
        {
            dataGridView1.Columns.Clear();

            dataGridView1.AutoGenerateColumns = false;
            //  dataGridView1.AutoSize = true;
            dataGridView1.DataSource = list;
          
            ColumnInitialize(dataGridView1);
            DataGridViewColumn column5 = new CalendarColumn();
            column5.DataPropertyName = "AddDate";
            column5.Name = "时间";
            dataGridView1.Columns.Insert(2,column5);


            // Initialize and add a text box column.
            DataGridViewColumn column1 = new DataGridViewTextBoxColumn();
            column1.DataPropertyName = "ContentSummary";
            column1.Name = "内容提要";
            column1.ReadOnly = false;

            dataGridView1.Columns.Insert(3, column1);

        


        }

        private void ColumnInitialize(DataGridView dataGridView1)
        {
            DataGridViewColumn column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "FirstLevel";
            column.Name = "科目";
            column.ReadOnly = true;
            dataGridView1.Columns.Add(column);

            DataGridViewColumn column10 = new DataGridViewTextBoxColumn();
            column10.DataPropertyName = "SecondLevel";
            column10.Name = "子科目";
            column10.ReadOnly = true;
            dataGridView1.Columns.Add(column10);

            DataGridViewColumn column2 = new DataGridViewTextBoxColumn();
            column2.DataPropertyName = "Income";
            column2.Name = "收入";
            dataGridView1.Columns.Add(column2);

            DataGridViewColumn column3 = new DataGridViewTextBoxColumn();
            column3.DataPropertyName = "Cost";
            column3.Name = "支出";
            dataGridView1.Columns.Add(column3);

            DataGridViewColumn column4 = new DataGridViewTextBoxColumn();
            column4.DataPropertyName = "ExistingIncome";
            column4.Name = "现有余额";
            dataGridView1.Columns.Add(column4);

            DataGridViewColumn column7 = new DataGridViewTextBoxColumn();
            column7.DataPropertyName = "ShouldHaveIncome";
            column7.Name = "应有余额";
            dataGridView1.Columns.Add(column7);

            DataGridViewColumn column8 = new DataGridViewTextBoxColumn();
            column8.DataPropertyName = "Borrow";
            column8.Name = "借入款（减）";
            dataGridView1.Columns.Add(column8);

            DataGridViewColumn column9 = new DataGridViewTextBoxColumn();
            column9.DataPropertyName = "Lent";
            column9.Name = "借出款（加）";
            dataGridView1.Columns.Add(column9);


            DataGridViewColumn column6 = new DataGridViewTextBoxColumn();
            column6.DataPropertyName = "Comment";
            column6.Name = "备注";
            dataGridView1.Columns.Add(column6);
        }

        public List<IItem> ReadCsvFile(string fileName)
        {
            string[] allLines = File.ReadAllLines(fileName);

            var query = from line in allLines.Skip(1)
                        where !string.IsNullOrEmpty(line)
                        let data = line.Replace("\"", string.Empty).Split(',')
                        select new Leaf
                        {
                            FirstLevel = data[0],
                            SecondLevel = data[1],
                            AddDate = (string.IsNullOrEmpty(data[2]) || data[2] == "\"\"") ? DateTime.MinValue : DateTime.ParseExact(data[2], "yyyy/MM/dd", System.Globalization.CultureInfo.InvariantCulture),
                            ContentSummary = data[3],
                            Income = data[4].ParseToDouble(),
                            Cost = data[5].ParseToDouble(),
                           // ExistingIncome = data[6].ParseToDouble(),
                           // ShouldHaveIncome = data[7].ParseToDouble(),
                            Borrow = data[8].ParseToDouble(),
                            Lent = data[9].ParseToDouble(),
                            Comment = data[10]
                            //Age = Convert.ToInt16(data[4])
                        };
            return query.Cast<IItem>().ToList();
        }
      
        
    }
}